package com.acme.service.bank.impl;

import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;

import com.acme.domain.account.Account;
import com.acme.domain.account.AccountType;
import com.acme.domain.client.Bank;
import com.acme.domain.client.Client;
import com.acme.service.bank.BankReportService;

public class BankReportServiceImpl implements BankReportService {

    @Override
    public String getAccountsSortedByDeposit(final Bank bank,
	    final boolean ascending) {
	List<Account> accounts = new LinkedList<>();
	StringBuilder report = new StringBuilder();
	for (Client client : bank.getClientsList()) {
	    accounts.addAll(client.getAccountsList());
	}
	Comparator<Account> accComparator = new Comparator<Account>() {

	    @Override
	    public int compare(Account a1, Account a2) {
		if(a1 == null || a2 == null) {
		    throw new NullPointerException();
		}
		if(a1.getBalance() == a2.getBalance()) {
		    return 0;
		} else if(a1.getBalance() > a2.getBalance()) {
		    return (ascending ? 1 : -1);
		}
		return (ascending ? -1 :1);
	    }
	};
	Collections.sort(accounts, accComparator);
	for(Account account: accounts) {
	    report.append(account);
	    report.append("\n");
	}
	return report.toString();
    }

    @Override
    public int getBankCredit(final Bank bank) {
	double credit = 0;
	List<Client> clients = bank.getClientsList();
	for (Client client : clients) {
	    for (Account account : client.getAccountsList()) {
		if (account.getAccountType().equals(AccountType.CHECKING)) {
		    credit += account.getMaximumAmountToWithdraw()
			    - account.getBalance();
		}
	    }
	}
	return (int) credit;
    }

    @Override
    public String getCustomerAccounts(final Bank bank) {
	StringBuilder report = new StringBuilder();
	;
	List<Client> clients = bank.getClientsList();
	for (Client client : clients) {
	    report.append(client);
	    report.append("\n\n");
	}
	return report.toString();
    }

    @Override
    public int getNumberOfAccounts(final Bank bank) {
	int counter = 0;
	List<Client> clients = bank.getClientsList();
	for (Client client : clients) {
	    counter += client.getAccountsList().size();
	}
	return counter;
    }

    @Override
    public int getNumberOfClients(final Bank bank) {
	return bank.getClientsList().size();
    }

    @Override
    public int getNumberOfOpenAccounts(final Bank bank) {
	int counter = 0;
	List<Client> clients = bank.getClientsList();
	for (Client client : clients) {
	    for (Account account : client.getAccountsList()) {
		if (account.isOpened()) {
		    counter++;
		}
	    }
	}
	return counter;
    }

}